package ca.camosun.bouncer;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import ca.camosun.bouncer.game.HighScores;
import ca.camosun.bouncer.game.SingleScore;
import android.app.Application;

public class Bouncer extends Application {

	private static final int MAXIMUM_NUMBER_OF_SCORES = 10;
	private static final String SCORE_FILE_NAME = "highScores.txt";
	private static final String DEFAULT_PLAYER_NAME = "Player";

	private String playerName;
	private HighScores<SingleScore> highScores;

	public Bouncer() {
		super();

		playerName = DEFAULT_PLAYER_NAME;
	}

	public String getPlayerName() {
		return playerName;
	}
	
	public boolean isHighScore(int points) {
		if (highScores.size() < MAXIMUM_NUMBER_OF_SCORES) {
			return true;
		}
		
		SingleScore lowestScore = (SingleScore) highScores.getLastOnList();
		
		if (points > lowestScore.getScore()) {
			return true;
		}
		
		return false;
	}

	public boolean isTopScore(int points) {
		if (highScores.size() == 0) {
			return true;
		}

		SingleScore topScore = (SingleScore) highScores.getFirstOnList();

		if (points > topScore.getScore()) {
			return true;
		}

		return false;
	}

	public void saveScore(String player, int points) {
		// TODO: Validate name.
		if (player.equals("")) {
			player = DEFAULT_PLAYER_NAME;
		}
		if(player.length() > 16){
			player = player.substring(0, 16);
		}
		player = player.replaceAll("[^a-zA-Z0-9] ", "");

		highScores.addScore(new SingleScore(player, points));

		try {
			FileOutputStream fOut = openFileOutput(SCORE_FILE_NAME, MODE_APPEND);
			OutputStreamWriter osw = new OutputStreamWriter(fOut);

			osw.append(player + " " + String.valueOf(points) + "\n");
			osw.flush();
			osw.close();

			System.out.println("Wrote to score file: player=" + player
					+ " points=" + String.valueOf(points));

		} catch (FileNotFoundException e) {
			e.printStackTrace();

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private List<SingleScore> getScores() {
		List<SingleScore> scores = new ArrayList<SingleScore>();

		for (int i = 0; i < highScores.size(); i++) {
			scores.add((SingleScore) highScores.get(i));
		}

		return scores;
	}

	public List<SingleScore> getHighScores() {
		if (highScores != null) {
			return getScores();
		}
		
		highScores = new HighScores<SingleScore>(MAXIMUM_NUMBER_OF_SCORES);

		File file = getBaseContext().getFileStreamPath(SCORE_FILE_NAME);

		if (!file.exists()) {
			System.out.println("Score file does not exist.");

			return getScores();
		}

		try {
			FileInputStream fis = openFileInput(SCORE_FILE_NAME);
			InputStreamReader inputStreamReader = new InputStreamReader(fis);
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);

			System.out.println("Reading score file:");

			Pattern scorePattern = Pattern.compile("(.+)\\s(\\d+)");

			String line;
			while ((line = bufferedReader.readLine()) != null) {
				Matcher scoreMatch = scorePattern.matcher(line);

				if (!scoreMatch.matches()) {
					System.out.println("Malformed score string: " + line);
					continue;
				}

				String name = scoreMatch.group(1);
				String scoreString = scoreMatch.group(2);
				int score;
				
				try {
					score = Integer.parseInt(scoreString); 
				} catch (NumberFormatException e) {
					System.out.println("Malformed score points: " + scoreString);
					continue;
				}

				highScores.addScore(new SingleScore(name, score));

				System.out.println("player=" + name + " points=" + score);
			}
			bufferedReader.close();

		} catch (IOException e) {
			e.printStackTrace();
		}

		return getScores();
	}

}
